﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using NPOI.SS.UserModel;
using NPOI.HSSF.UserModel;
using System.Data;
using NPOI.XSSF.UserModel;

namespace ArcGisMapDesktop
{
    /// <summary>
    /// NPOI公共类
    /// </summary>
    public class ExcelHelper : IDisposable
    {
        private string fileName = null; // 文件名
        private IWorkbook workbook = null;
        private FileStream fs = null;
        private bool disposed;
        public ExcelHelper(string fileName)
        {
            this.fileName = fileName;
            disposed = false;
        }
        /// <summary>
        /// 根据list导入Excel
        /// </summary>
        /// <typeparam name="T">实体对象</typeparam>
        /// <param name="list">实体集合</param>
        /// <param name="TempletFileName">模板路径</param>
        /// <param name="celNames">导入列名</param>
        /// <param name="sheetIndex">导入第几个sheet</param>
        /// <param name="startRowIndex">开始导入索引</param>
        /// <returns></returns>
        public string DataTableToExcel<T>(List<T> list, string celNames, int sheetIndex = 0, int startRowIndex = 1)
        {
            DataTable dt = new ListToDataTable().ToDataTable<T>(list);
            return DataTableToExcel(dt, celNames, sheetIndex, startRowIndex);
        }
        /// <summary>
        /// 讲dataTable数据导入Excel中
        /// </summary>
        /// <param name="data">数据源</param>
        /// <param name="TempletFileName">模板路径</param>
        /// <param name="celNames">导入列名</param>
        /// <param name="sheetIndex">导入到第几个索引中</param>
        /// <param name="startRowIndex">开始导入行数</param>
        /// <returns>返回导入后的路径</returns>
        public string DataTableToExcel(DataTable data, string celNames, int sheetIndex = 0, int startRowIndex = 1)
        {
            int i = 0;
            int j = 0;
            int count = startRowIndex;
            try
            {
                string ReportFileName = System.AppDomain.CurrentDomain.BaseDirectory + "\\" + "Excel" + DateTime.Now.Ticks + ".xlsx";
                string[] celNameArry = celNames.Split(',');
                workbook = GetWorkBook();
                ISheet sheet = workbook.GetSheetAt(sheetIndex);
                for (i = 0; i < data.Rows.Count; ++i)
                {
                    IRow row = sheet.CreateRow(count);
                    for (j = 0; j < celNameArry.Length; ++j)
                    {
                        row.CreateCell(j).SetCellValue(data.Rows[i][celNameArry[j]].ToString());
                    }
                    ++count;
                }
                sheet.ForceFormulaRecalculation = true;

                using (FileStream filess = File.OpenWrite(ReportFileName))
                {
                    workbook.Write(filess);
                }
                return ReportFileName;
            }
            catch (Exception ex)
            {
                //Logs.Error("导入Excel报错：" + ex.ToString());
            }

            return string.Empty;
        }

        IWorkbook GetWorkBook()
        {
            if (string.IsNullOrEmpty(fileName))
            {
                workbook = new XSSFWorkbook();
                return workbook;
            }
            FileInfo fileInfo = new FileInfo(fileName);
            FileStream file = new FileStream(this.fileName, FileMode.Open, FileAccess.Read);
            if (fileInfo.Extension == ".xls")
            {
                try
                {
                    workbook = new HSSFWorkbook(file);
                }
                catch (Exception ex)
                {
                    //Logs.Error(ex);
                    workbook = new XSSFWorkbook(file);
                }
            }
            else
            {
                workbook = new XSSFWorkbook(file);
            }
            return workbook;
        }
        /// <summary>
        /// 讲dataTable数据导入Excel中
        /// </summary>
        /// <param name="data">数据源</param>
        /// <param name="TempletFileName">模板路径</param>
        /// <param name="celNames">导入列名</param>
        /// <param name="sheetName">导入到第几个索引中</param>
        /// <param name="startRowIndex">开始导入行数</param>
        /// <returns>返回导入后的路径</returns>
        public string DataTableToExcel(DataTable data, string celNames, string sheetName, int startRowIndex = 1)
        {
            int i = 0;
            int j = 0;
            int count = startRowIndex;
            try
            {
                string ReportFileName = System.AppDomain.CurrentDomain.BaseDirectory + "\\" + "Excell" + DateTime.Now.Ticks + ".xlsx";
                string[] celNameArry = celNames.Split(',');
                workbook = GetWorkBook();
                ISheet sheet = workbook.GetSheet(sheetName);
                for (i = 0; i < data.Rows.Count; ++i)
                {
                    IRow row = sheet.CreateRow(count);
                    for (j = 0; j < celNameArry.Length; ++j)
                    {
                        row.CreateCell(j).SetCellValue(data.Rows[i][celNameArry[j]].ToString());
                    }
                    ++count;
                }
                sheet.ForceFormulaRecalculation = true;

                using (FileStream filess = File.OpenWrite(ReportFileName))
                {
                    workbook.Write(filess);
                }
                return ReportFileName;
            }
            catch (Exception ex)
            {
                //Logs.Error("导入Excel报错：" + ex.ToString());
            }

            return string.Empty;
        }
        /// <summary> 将excel中的数据导入到DataTable中 </summary>
        /// <param name="sheetName"> excel工作薄sheet的名称 </param>
        /// <param name="isFirstRowColumn"> 第一行是否是DataTable的列名 </param> 
        /// <param name="workbookData"> 工作簿内容 </param>  
        /// <returns> 返回的DataTable </returns> 
        public DataTable ExcelToDataTable(string sheetName, bool isFirstRowColumn, IWorkbook workbookData)
        {
            ISheet sheet = null;
            DataTable dt = new DataTable();
            int startRow = 0;
            try
            {
                //如果workbookData为空，则重新打开Excel文件
                if (workbookData == null)
                {
                    workbook = GetWorkBook();
                }
                else
                {
                    workbook = workbookData;
                }
                if (!string.IsNullOrEmpty(sheetName))
                {
                    sheet = workbook.GetSheet(sheetName);
                    dt.TableName = sheetName;
                }
                else
                {
                    sheet = workbook.GetSheetAt(0);
                    dt.TableName = workbook.GetSheetName(0);
                }
                if (sheet != null)
                {
                    IRow firstRow = sheet.GetRow(0);
                    if (firstRow == null)
                    {
                        return dt;
                    }
                    int cellCount = firstRow.LastCellNum; // 一行最后一个cell的编号 即总的列数 
                    if (isFirstRowColumn)
                    {

                        for (int i = firstRow.FirstCellNum; i < cellCount; ++i)
                        {
                            if (firstRow.GetCell(i) != null)
                            {
                                firstRow.GetCell(i).SetCellType(CellType.String);//全部格式为字符串
                            }
                            else
                            {
                                throw new Exception("第一行列名不能为NULL");
                            }
                            var StringCellValue = firstRow.GetCell(i) != null ? firstRow.GetCell(i).StringCellValue : string.Empty;
                            DataColumn column = new DataColumn(StringCellValue);
                            dt.Columns.Add(column);
                        }
                        startRow = sheet.FirstRowNum + 1;
                    }
                    else
                    {
                        startRow = sheet.FirstRowNum;
                    }

                    // 最后一列的标号 
                    int rowCount = sheet.LastRowNum;
                    for (int i = startRow; i <= rowCount; ++i)
                    {
                        IRow row = sheet.GetRow(i);
                        if (row == null) continue; // 没有数据的行默认是null　　　
                        DataRow dataRow = dt.NewRow();
                        for (int j = row.FirstCellNum; j < cellCount; ++j)
                        {
                            if (row.GetCell(j) != null) // 同理，没有数据的单元格都默认是null 
                            {
                                ICell cell = row.GetCell(j);
                                switch (cell.CellType)
                                {
                                    case CellType.Blank://空数据值处理
                                        dataRow[j] = "";
                                        break;
                                    case CellType.String://字符串类型
                                        dataRow[j] = cell.StringCellValue;
                                        break;
                                    case CellType.Numeric://数字类型 
                                        if (DateUtil.IsCellDateFormatted(cell))
                                        {
                                            dataRow[j] = cell.DateCellValue;
                                        }
                                        else
                                        {
                                            dataRow[j] = cell.NumericCellValue;
                                        }
                                        break;
                                    case CellType.Formula:
                                        HSSFFormulaEvaluator e = new HSSFFormulaEvaluator(workbook);
                                        dataRow[j] = e.Evaluate(cell).StringValue;
                                        break;
                                    default:
                                        dataRow[j] = "";
                                        break;


                                }
                            }
                        }
                        dt.Rows.Add(dataRow);
                    }
                }

                return dt;
            }
            catch (Exception ex)
            {
                /// this.LogError(null, "获取要导入的Excel数据出错:  " + ex.Message);
                throw new Exception("获取要导入的Excel数据出错:  " + ex.Message);
            }
        }
        /// <summary>
        /// 多个Sheet1导入到DataSet
        /// </summary>
        /// <param name="isFirstRowColumn">第一行是否是DataTable的列名</param>
        /// <returns></returns>
        public DataSet ExcelToDataSet(bool isFirstRowColumn)
        {
            DataSet ds = new DataSet();
            IWorkbook workbook = null;
            try
            {
                workbook = GetWorkBook();
            }
            catch (Exception ex)
            {
                //Logs.Error(ex);
                ///HSSFWorkbook 不能装载 装载有异常 那就是Excel2007版本以上的版本
                fs = new FileStream(fileName, FileMode.Open, FileAccess.Read);
                workbook = new XSSFWorkbook(fs);
            }
            int x = workbook.NumberOfSheets;
            //List<string> sheetNames = new List<string>();
            for (int i = 0; i < x; i++)
            {
                ds.Tables.Add(ExcelToDataTable(workbook.GetSheetName(i), isFirstRowColumn, workbook));
                //sheetNames.Add(workbook.Workbook.GetSheetName(i));
            }
            return ds;
        }
        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        protected virtual void Dispose(bool disposing)
        {
            if (!this.disposed)
            {
                if (disposing)
                {
                    if (fs != null)
                        fs.Close();
                }

                fs = null;
                disposed = true;
            }
        }


    }
}
